#include "e2d/core/physics/PhysicsSystem.h"
#include "e2d/core/physics/RigidbodyStatic.h"
#include "e2d/core/physics/RigidbodyDynamic.h"
#include "e2d/core/Entity.h"

using namespace physx;

namespace
{

};


e2d::PhysicsSystem::PhysicsSystem()
{
	e2d::PxUtils::gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, e2d::PxUtils::gAllocator, e2d::PxUtils::gErrorCallback);
	e2d::PxUtils::gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *e2d::PxUtils::gFoundation, PxTolerancesScale(), true);
	e2d::PxUtils::gDispatcher = PxDefaultCpuDispatcherCreate(2);

	PxSceneDesc sceneDesc(e2d::PxUtils::gPhysics->getTolerancesScale());
	sceneDesc.cpuDispatcher = e2d::PxUtils::gDispatcher;
	sceneDesc.filterShader = PhysicsTriggerCallback::DefaultFilterShader;

	e2d::PxUtils::gScene = e2d::PxUtils::gPhysics->createScene(sceneDesc);
	e2d::PxUtils::gScene->setSimulationEventCallback(new PhysicsTriggerCallback());

	e2d::PxUtils::gScene->setGravity({ 0,-9.8f,0.f });

}

void e2d::PhysicsSystem::OnLoad()
{
	LoadView<e2d::RigidbodyDynamic>();
	LoadView<e2d::RigidbodyStatic>();

}

void e2d::PhysicsSystem::OnStart()
{
}

void e2d::PhysicsSystem::OnUpdateRuntime()
{
	auto timer = m_Scene->m_Timer;

	for (auto e : m_Scene->GetComponentEntities<e2d::RigidbodyDynamic>())
	{
		auto& rb = e->Get<e2d::RigidbodyDynamic>();
		rb.PushTransform();
	}
	if (e2d::PxUtils::gScene)
	{
		e2d::PxUtils::gScene->simulate(timer->DeltaTime());
		e2d::PxUtils::gScene->fetchResults(true);
	}
	UpdateViewRuntime<e2d::RigidbodyStatic>();
	UpdateViewRuntime<e2d::RigidbodyDynamic>();

}

void e2d::PhysicsSystem::OnUpdate()
{
}

void e2d::PhysicsSystem::OnDestory()
{
	Delete();
}

void e2d::PhysicsSystem::Delete()
{
	//if (m_PhysicsTriggerCallback)
	//{
	//	delete m_PhysicsTriggerCallback;
	//	m_PhysicsTriggerCallback = 0;
	//}

	//if (e2d::PxUtils::gScene)
	//{
	//	e2d::PxUtils::gScene->release();
	//	e2d::PxUtils::gScene = 0;
	//}
	//if (e2d::PxUtils::gDispatcher)
	//{
	//	e2d::PxUtils::gDispatcher->release();
	//	e2d::PxUtils::gDispatcher = 0;
	//}
	//if (e2d::PxUtils::gPhysics)
	//{
	//	e2d::PxUtils::gPhysics->release();
	//	e2d::PxUtils::gPhysics = 0;
	//}
	//if(e2d::PxUtils::gFoundation)
	//{
	//	e2d::PxUtils::gFoundation->release();
	//	e2d::PxUtils::gFoundation = 0;

	//}

}
